// 引入three.js
import * as THREE from 'three';
import { LineSegments2 } from 'three/examples/jsm/lines/LineSegments2'
import { Line2 } from 'three/examples/jsm/lines/Line2'
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry'
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial'


// pointsArrs：一个行政区包含一个或多个轮廓，一个轮廓对应pointsArrs的一个元素
function borderLine(pointsArrs, width, height) {
    var group = new THREE.Group();//一个国家多个轮廓线条line的父对象
    pointsArrs.forEach(polygon => {
        var pointArr = [];//边界线顶点坐标
        polygon[0].forEach(elem => {
            pointArr.push(elem[0], elem[1], 0);
        });
        group.add(oneBorderLine2(pointArr, width, height, 0x5ce3f5, 4).line);
    });
    return group;
}

// 这个是可以设置线条宽度的
function oneBorderLine2(pointArr, width, height, color = 0x2e21bd, linewidth = 2, vertexColors = false, vertexColorList = []) {
    // console.log(pointArr);
    var geometry = new LineGeometry(); //创建一个Buffer类型几何体对象
    geometry.setPositions(pointArr);
    var material = null;
    if (vertexColors) {
        geometry.setColors(vertexColorList);
        material = new LineMaterial({
            // 线宽度
            linewidth,
            vertexColors: true,
        });
    } else {
        material = new LineMaterial({
            color,
            // 线宽度
            linewidth,
        });
    }

    material.resolution.set(width, height);
    var line = new Line2(geometry, material);

    return { line, geometry };
}


// 生成飞线
const flyLine = (pointArr, colorArr, width, height, strudeHeight) => {
    const geometry = new LineGeometry();
    geometry.setPositions(pointArr);
    geometry.setColors(colorArr);
    const material = new LineMaterial({
        // color: 0xffff00,//使用顶点颜色，材质颜色不用设置
        vertexColors: true, //使用顶点颜色插值计算
        linewidth: 4.0, // 设置线宽
    });
    material.resolution.set(width, height);
    const flyline = new Line2(geometry, material);
    flyline.position.z = strudeHeight
    return flyline
}


// 生成普通线条
const normalLine = (from, to, box, strudeHeight) => {
    // 插入飞线
    const start = new THREE.Vector3(from.E, from.N, 0); //起点
    const end = new THREE.Vector3(to.E, to.N, 0); //终点
    const middle = new THREE.Vector3(0, 0, 0);
    middle.add(start).add(end).divideScalar(2);
    // 根据两点之间距离计算轨迹线高度
    const L = start.clone().sub(end).length();//地图上两点之间距离

    const randomHeight = Math.random() * 0.1 + 0.1
    const H = L * randomHeight; //轨迹线高度，注意考虑两点距离来设置，弧线高度和两点之间距离正相关
    middle.z += H;
    // if(Math.random() < 0.5){
    //     middle.x += Math.random() * 0.16
    //     // middle.y += Math.random() * 0.2
    // } else {
    //     middle.x -= Math.random() * 0.16
    //     // middle.y -= Math.random() * 0.2
    // }

    //创建线条模型
    // const geometry = new THREE.BufferGeometry(); //创建一个缓冲类型几何体
    // 三维样条曲线
    const curve = new THREE.CatmullRomCurve3([
        start,
        middle,
        end,
    ]);
    //曲线上等间距返回多个顶点坐标
    const points = curve.getSpacedPoints(100); //分段数100，返回101个顶点
    const newPoints = vector3ArrToNormal(points)
    const geometry = new LineGeometry(); //创建一个Buffer类型几何体对象
    geometry.setPositions(newPoints);
    const material = new LineMaterial({
        color: 0x259cac,
        linewidth: 6.0,
    });
    material.resolution.set(box.clientWidth, box.clientHeight);
    //线条模型对象
    const line = new Line2(geometry, material);
    //注意考虑地图拉伸高度
    line.position.z = strudeHeight;
    line.flyTrackPoints = points;
    return line;
}

// 三维向量数组替换成普通数组  三个元素代表一个点位的xyz值
const vector3ArrToNormal = (vector3Arr = []) => {
    const arr = []
    vector3Arr.forEach(item => arr.push(item.x, item.y, item.z))
    return arr
}
const flylineFun = (index, points, box) => {
    // var choosePoints = []; //存储飞线轨迹上选择的顶点坐标，用于飞线绘制
    var num = 10; //从曲线上取11个点 飞线长度占飞线轨迹长度的10%  你可通过获取的点数调节飞线长度
    // for (var i = 0; i < num; i++) choosePoints.push(points[i + index]);

    const choosePoints = points.slice(index, index + num);
    const arr = vector3ArrToNormal(choosePoints);
    // 创建一个LineGeometry几何体
    var geometry = new LineGeometry();

    geometry.setPositions(arr);
    // geometry.boundingSphere.radius = ''
    //设置几何体顶点颜色值，进行插值计算
    var colorArr = []
    for (var i = 0; i < arr.length; i++) {
        var color1 = new THREE.Color(0x259cac); //飞线轨迹相近的颜色
        var color2 = new THREE.Color(0xffffff);
        var colo = null
        // posNum：插值计算的临界值  对应color2
        // var posNum = points.length/2;//飞线段，黄色居中，两侧青色
        var posNum = arr.length - 2;
        if (i < posNum) {
            colo = color1.lerp(color2, (i + 15) / posNum)
        } else {
            colo = color2.lerp(color1, (i - posNum) / (arr.length - posNum))
        }
        colorArr.push(colo.r, colo.g, colo.b)
    }

    geometry.setColors(colorArr);
    //几何体LineGeometry对应的材质LineMaterial
    var material = new LineMaterial({
        // color: 0x67e8ff,//使用顶点颜色，材质颜色不用设置
        vertexColors: true, //使用顶点颜色插值计算
        linewidth: 6.3, // 设置线宽
    });
    //材质输入Three.js渲染canvas画布的宽高度
    material.resolution.set(box.clientWidth, box.clientHeight);
    var flyline = new Line2(geometry, material);
    // 自定义飞线属性flyline.num、flyline.index，用于飞线动画
    flyline.num = num;
    flyline.index = index;
    console.log('=========', flyline);
    return flyline;
}

/**
 * 
 * @param {*} flyline 飞线线段本体mesh
 * @param {*} index 起始点位  每秒自增
 * @param {*} points 该线段所有点位合集
 */
const updateFlyGeo = (flyline, points) => {
    const currentPoints = points.slice(flyline.index, flyline.index + flyline.num);
    const arr = vector3ArrToNormal(currentPoints);
    // 设置几何体顶点位置坐标
    flyline.geometry.setPositions(arr);
    flyline.geometry.verticesNeedUpdate = true; //通知three.js几何体顶点位置坐标数据更新
}

export { borderLine, oneBorderLine2, flyLine, normalLine, flylineFun, updateFlyGeo };